<html>
  <head>
	  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>i5ting_ztree_toc:</title>
		<link href="toc/style/github-bf51422f4bb36427d391e4b75a1daa083c2d840e.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/style/github2-d731afd4f624c99a4b19ad69f3083cd6d02b81d5.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/css/zTreeStyle/zTreeStyle.css" media="all" rel="stylesheet" type="text/css"/>
	  <style>
		pre {
		    counter-reset: line-numbering;
		    border: solid 1px #d9d9d9;
		    border-radius: 0;
		    background: #fff;
		    padding: 0;
		    line-height: 23px;
		    margin-bottom: 30px;
		    white-space: pre;
		    overflow-x: auto;
		    word-break: inherit;
		    word-wrap: inherit;
		}

		pre a::before {
		  content: counter(line-numbering);
		  counter-increment: line-numbering;
		  padding-right: 1em; /* space after numbers */
		  width: 25px;
		  text-align: right;
		  opacity: 0.7;
		  display: inline-block;
		  color: #aaa;
		  background: #eee;
		  margin-right: 16px;
		  padding: 2px 10px;
		  font-size: 13px;
		  -webkit-touch-callout: none;
		  -webkit-user-select: none;
		  -khtml-user-select: none;
		  -moz-user-select: none;
		  -ms-user-select: none;
		  user-select: none;
		}

		pre a:first-of-type::before {
		  padding-top: 10px;
		}

		pre a:last-of-type::before {
		  padding-bottom: 10px;
		}

		pre a:only-of-type::before {
		  padding: 10px;
		}

		.highlight { background-color: #ffffcc } /* RIGHT */
		</style>
  </head>
  <body>
	  <div>
				<div style='width:25%;'>
						<ul id="tree" class="ztree" style='width:100%'>

						</ul>
				</div>
        <div id='readme' style='width:70%;margin-left:20%;'>
          	<article class='markdown-body'>
            	<h1 id="nodejs">nodeJs</h1>
<h2 id="-nodejs">初识nodeJs</h2>
<blockquote>
<p>Node.js@ is a JavaScript runtime built on Chrome&#39;s V8 JavaScript engine.Node.js </p>
<p>是一个基于 Chrome V8引的JavaScript 运行环境</p>
</blockquote>
<p><strong>js在浏览器中运行证明是前端开发，js放在node中运行就是后端开发</strong></p>
<p>Node.js 的官网地址: <a href="https://nodejs.org/en">Node.js (nodejs.org)</a></p>
<h3 id="nodejs-js-">nodeJs中的js运行</h3>
<p><img src=".\pic\node在js运行环境.png" alt="node在js运行环境"></p>
<ul>
<li>浏览器是JavaScript 的前端运行环境</li>
<li>Node.js 是JavaScript 的后端运行环境</li>
<li>Node.js 中无法调用 DOM 和 BOM等浏览器内置 API</li>
</ul>
<h3 id="nodejs-">nodeJs可以做什么</h3>
<blockquote>
<p>Nodejs 作为一个JavaScript 的运行环境，仅仅提供了基础的功能和 AP。然而，基于 Node.js 提供的这些基础能，很多强大的工具和框架如雨后春笋，层出不穷，所以学会了 Node.js，可以让前端程序员胜任更多的工作和岗位:</p>
</blockquote>
<ul>
<li>基于Express 框架(<a href="http://www.expressjs.com.cn/)，可以快速构建">http://www.expressjs.com.cn/)，可以快速构建</a> Web 应用</li>
<li>基于Electron框架(<a href="https://electronjs.org/)，可以构建跨平台的桌面应用">https://electronjs.org/)，可以构建跨平台的桌面应用</a></li>
<li>基于restify 框架(<a href="http://restify.com/)，可以快速构建API">http://restify.com/)，可以快速构建API</a> 接口项目</li>
<li>读写和操作数据库、创建实用的命令行工具辅助前端开发、etc...</li>
</ul>
<p><em>Node,js 的学习路径:
JavaScript 基础语法 + Nodejs 内置 API 模块 (fs、 path http等) + 第=方 API 模块 (express、 mysql等)</em></p>
<h3 id="-nodejs">下载nodeJs</h3>
<p><img src=".\pic\下载node.png" alt="下载node"></p>
<p>然后安装</p>
<h4 id="-lts-current-">区分LTS和Current版本的不同</h4>
<ul>
<li>LTS为长期稳定版，对于追求稳定性的企业级项目来说，推荐安装LTS版本的Node.js</li>
<li>Current 为新特性尝鲜版，对热衷于尝试新特性的用户来说，推荐安装 Current 版本的 Node.js。但是，Current 版本中可2能存在隐藏的Bug 或安全性漏洞因此不推荐在企业级项目中使用Current 版本的Nodejs</li>
</ul>
<h4 id="-node-">查看node版本</h4>
<pre><code>node -v
</code></pre><h4 id="nodej-js-">nodeJ运行JS代码</h4>
<pre><code class="lang-shell">node js文件
</code></pre>
<h2 id="fs-">fs模块</h2>
<blockquote>
<p>fs 模块是 ode.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性，用来满足用户对文件的操作需求.</p>
</blockquote>
<ul>
<li>fs.readFile0 方法，用来读取指定文件中的内容</li>
<li>fs.writeFile0 方法，用来向指定的文件中写入内容</li>
</ul>
<h3 id="fs-readfile">fs.readFile</h3>
<pre><code class="lang-js">fs.readFile(path,[，options],callback)
</code></pre>
<ul>
<li><p>参数1:必选参数，字符串，表示文件的路径</p>
</li>
<li><p>参数2:可选参数，表示以什么编码格式来读取文件</p>
</li>
<li><p>参数3:必选参数，文件读取完成后，通过回调函数拿到读取的结果</p>
</li>
</ul>
<blockquote>
<p>示例代码</p>
</blockquote>
<pre><code class="lang-js">const fs = require(&#39;fs&#39; )
fs.readFile(&#39;/files/11.txt&#39;,&#39;utf8&#39;,function(edataStr){
    console.log(err)
    console.log(&#39;-----&#39;)
    console.log(dataStr)
})
</code></pre>
<pre><code class="lang-js">// 导入模块
const fs = require(&#39;fs&#39;)
//  2.调用 fs.readFile() 方法读取文件
// 参数1: 读取文件的存放路径
// 参数2: 读取文件时候采用的编码格式，一般默认指定 utf8
// 参数3: 回调函数，拿到读取失败和成功的结果err dataStr
fs.readFile(&#39;./read.tex&#39;,&#39;utf-8&#39;,function(err,dataStr){
    // 如果读取失败了 则err为null
    // 读取失败则err的值为 错误对象，dataStr的值为undefined
    console.log(dataStr)
})
</code></pre>
<h4 id="-">判断文件是否读取成功</h4>
<pre><code class="lang-js">// 导入模块
const fs = require(&#39;fs&#39;)
fs.readFile(&#39;./rea.tex&#39;, &#39;utf-8&#39;, function (err, dataStr) {
    if (err) {
        return console.log(&quot;文件读取失败&quot; + err);
    } else {
        console.log(dataStr);
    }
})
</code></pre>
<h3 id="fs-writefile">fs.writeFile</h3>
<pre><code class="lang-js">fs.writeFile(feil,[，options],callback)
</code></pre>
<ul>
<li><p>参数1:必选参数，需要指定一个文件路径的字符串，表示文件的存放路径</p>
</li>
<li><p>参数2:必选参数，表示要写入的内容</p>
</li>
<li><p>参数3:可选参数，表示以什么格式写入文件内容，默认值是utf8</p>
</li>
<li><p>参数4:必选参数，文件写入完成后的回调函数</p>
</li>
</ul>
<blockquote>
<p>示例代码</p>
</blockquote>
<pre><code class="lang-js">const fs = require(&#39;fs&#39;)
fs.writeFile(&#39;./files/2.txt&#39;, &#39;Hello Node.js!&#39;, function (err) {
    console.log(err)
})
</code></pre>
<pre><code class="lang-js">// 导入fs模块
const fs = require(&#39;fs&#39;)
// 写入文件方法
// 2.调用 fs.writeFile() 方法，写入文件的内容
// 参数1: 表示文件的存放路径
// 参数2: 表示要写入的内容
// 参数3: 回调函数
fs.writeFile(&quot;./feil/read1.tex&quot;,&#39;hello你好&#39;,function(err){
    // 如果写入成功，则err为null
    // 如果文件写入失败,则err等于一个 错误对象
    console.log(err)
})
</code></pre>
<h4 id="-">判断文件是否读取成功</h4>
<pre><code class="lang-js">// 导入模块
const fs = require(&#39;fs&#39;)

fs.writeFile(&quot;./feil/read1.tex&quot;,&#39;hello你好&#39;,function(err){
    if(err){
        return console.log(&quot;文件写入失败&quot; + err.message)
    }
    console.log(&quot;文件写入成功&quot;)
})
</code></pre>
<h3 id="-">整理考试成绩</h3>
<p>核心实现步骤</p>
<ul>
<li><p>导入需要的 fs文件系统模块</p>
</li>
<li><p>使用 fs.readFile()方法，读取素材目录下的 成绩.txt 文件</p>
</li>
<li><p>判断文件是否读取失败</p>
</li>
<li><p>文件读取成功后，处理成绩数据</p>
</li>
<li><p>将处理完成的成绩数据，调用 fs.writeFile()方法，写入到新文件成绩-ok.txt 中</p>
</li>
</ul>
<pre><code class="lang-js">const fs = require(&#39;fs&#39;);
fs.readFile(&#39;./feil/成绩.tex&#39;,&#39;utf-8&#39;,function(err,dataStr){
    if(err){
        return console.log(&quot;文件读取失败&quot; + err);
    }
    // 先把成绩的数据,安装空格进行分割
    const arrOld = dataStr.split(&quot; &quot;);
    // 循环分割后的数组,对每一个数据进行字符串的替换操作
    const arrNew = [];
    arrOld.forEach(item =&gt; {
        arrNew.push(item.replace(&#39;=&#39;,&quot;:&quot;))
    })
    // 新数组的每一个,进行合并,得到一个新的字符串
    const newStr = arrNew.join(&#39;\r\n&#39;);
    fs.writeFile(&#39;./feil/成绩-ok.tex&#39;,newStr,function(err){
        if(err){
            return console.log(&quot;文件写入失败&quot; + err.message)
        }
        console.log(&quot;文件写入成功&quot;)
    })
})
</code></pre>
<h3 id="fs-">fs路径动态拼接的问题</h3>
<blockquote>
<p>在使用s 模块操作文件时，如果提供的操作路径是以../或./开头的相对路径时，很容易出现路径动态拼接错误的问题，</p>
</blockquote>
<p><strong>原因:代码在运行的时候，会以执行 node 命令时所处的目录，动态拼接出被操作文件的完整路径</strong></p>
<ol>
<li><p>可以提供一个完整的文件路径,移植性非常差,不利于后期的维护</p>
</li>
<li><p>使用__dirname,表示当前文件的所处目录</p>
<pre><code class="lang-js"> const fs = require(&#39;fs&#39;);
 // 表示当前所处的目录
 console.log(__dirname)

 fs.readFile(__dirname + &quot;/feil/成绩.tex&quot;,&#39;utf-8&#39;,function(err,dataStr){
     if(err){
         return console.log(&quot;文件读取失败&quot; + err.message)
     }
     console.log(&#39;文件读取成功&#39;)
     console.log(dataStr)
 })
</code></pre>
</li>
<li><p>使用path模块解决</p>
</li>
</ol>
<h2 id="path-">path模块</h2>
<blockquote>
<p>path 模块是 Node.js 官方提供的、用来处理路径的模块。它提供了一系列的方法和属性，用来满足用户对路径的处理需求。
例如:</p>
<ul>
<li>path.join0 方法，用来将多个路径片段拼接成一个完整的路径字符串</li>
</ul>
</blockquote>
<ul>
<li>path.basename0 方法，用来从路径字符串中，将文件名解析出来</li>
</ul>
<p>如果要在JavaScript代码中，使用 path 模块来处理路径，则需要使用如下的方式先导入它</p>
<pre><code class="lang-js">const path = require(&#39;path&#39;);
</code></pre>
<h3 id="path-join-">path.join()</h3>
<blockquote>
<p>使用 path.join()方法，可以把多个路径片段拼接为完整的路径字符串，语法格式如下:</p>
</blockquote>
<pre><code class="lang-js">path.join([...paths])
</code></pre>
<p>参数解读:</p>
<ul>
<li>...paths<string>路径片段的序列</li>
<li>返回值: <string></li>
</ul>
<blockquote>
<p>示例代码</p>
</blockquote>
<pre><code class="lang-js">const pathStr = path.join(&#39;/a&#39;,&#39; /b/c&#39;,&#39;../&#39;,&#39;/d&#39;,&#39;/e&#39;)
// ../会将前面的一层路径抵消掉
console.log(pathStr) // 输出  a\bid\e
const pathStr2 = path.join(__dirname,&#39;./files/1 .txt&#39;)
console.log(pathStr2) // 输出 当前文件所处目录 \files\1.txt
</code></pre>
<pre><code class="lang-js">const path = require(&#39;path&#39;);
const pathStr = path.join(&#39;/e&#39;,&#39;/d/e/c&#39;,&#39;../&#39;,&#39;/e&#39;,&#39;./&#39;,&#39;e&#39;);

console.log(pathStr)  // \e\d\e\e\e

</code></pre>
<p><strong><font color='red'>今后涉及到路径的拼接的操作,都要使用path.join()方法进行处理,不要直接使用 + 进行字符串拼接</font></strong></p>
<h3 id="path-basename-">path.basename()</h3>
<blockquote>
<p>使用 path.basename方法，可以获取路径中的最后一部分，经常通过这个方法获取路径中的文件名</p>
</blockquote>
<pre><code class="lang-js">path.basename(path[,ext])
</code></pre>
<ul>
<li><p>path<string>必选参数，表示一个路径的字符串</p>
</li>
<li><p>ext<string>可选参数，表示文件扩展名</p>
</li>
<li><p>返回:<string>表示路径中的最后一部分</p>
</li>
</ul>
<blockquote>
<p>示例代码</p>
</blockquote>
<pre><code class="lang-js">const fpath =&#39;/a/b/c/index.htm&#39; // 文件的存放路径
var fullName = path.basename(fpath)
console.log(fullName) // 输出 index.html
var nameWithoutExt = path.basename(fpath,&#39;.html&#39; )
console.log(nameWithoutExt) // 输出 index
</code></pre>
<pre><code class="lang-js">const path = require(&#39;path&#39;);
const fpath = &#39;/a/b/c/index.html&#39;;
const fullNname = path.basename(fpath);

console.log(fullNname) // index.html

const fullNnameEnd = path.basename(fpath,&#39;.html&#39;);
console.log(fullNnameEnd); // index

</code></pre>
<h3 id="path-extname-">path.extname()</h3>
<blockquote>
<p>使用 path.extname方法，可以获取路径中的扩展名部分，语法格式如下</p>
</blockquote>
<pre><code class="lang-js">path.extname(path)
</code></pre>
<ul>
<li><p>path<string>必选参数，表示一个路径的字符串</p>
</li>
<li><p>返回:<string>返回得到的扩展名字符串</p>
</li>
</ul>
<blockquote>
<p>示例代码</p>
</blockquote>
<pre><code class="lang-js">const fpath = &#39;/a/b/c/index.html&#39; //.
路径字符串
const fext = path.extname(fpath)
console.log(fext) // 输出 .html
</code></pre>
<pre><code class="lang-js">const path = require(&#39;path&#39;);

const fpath = &#39;a/a/b/ac/index.js&#39;
const fext = path.extname(fpath)
console.log(fext) // .js

</code></pre>
<h3 id="path-">path路径案例</h3>
<p><img src=".\pic\时钟.png" alt="时钟案例"></p>
<pre><code class="lang-tex">将素材目录下的index.html页面拆分成三个文件，分别是:
    index.css
    indexjs
    index.html
并且将拆分出来的3个文件，存放到 clock 目录中。
</code></pre>
<h4 id="-">案例的实现步骤</h4>
<ul>
<li><p>创建两个正则表达式，分别用来匹配<style>和<script>标签</p>
</li>
<li><p>使用fs模块，读取需要被处理的HTML文件</p>
</li>
<li><p>自定义 resolveCSS 法，来写入 index.css 样式文件</p>
</li>
<li><p>自定义resolveJS 方法，来写入indexjs 脚本文件</p>
</li>
<li><p>自定义resolveHTML方法，来写入index.html文件</p>
</li>
</ul>
<pre><code class="lang-js">const path = require(&#39;path&#39;);
const fs = require(&#39;fs&#39;);

// 创建正则表达式
// \s匹配空白字符 \S匹配非空白字符 *匹配任意次
const regStyle = /&lt;style&gt;[\s\S]*&lt;\/style&gt;/;
const regScript = /&lt;script&gt;[\s\S]*&lt;\/script&gt;/;

fs.readFile(path.join(__dirname,&quot;../素材/index.html&quot;),&#39;utf-8&#39;,function(err,dataStr){
    // 文件读取失败的回调
    if(err) return console.log(&#39;读取文件失败&#39; + err.message);
    // 文件读取成功的回调
    // 处理css文件
    resolveCss(dataStr);
    // 处理js文件
    resolveScript(dataStr);
    // 处理html文件
    resolveHtml(dataStr)
})
// 处理css的方法
function resolveCss(htmlStr){
    // 使用正则提取需要的内容
    const r1 = regStyle.exec(htmlStr);
    // 将提取的内容进行replace替换操作
    const newCss = r1[0].replace(&#39;&lt;style&gt;&#39;,&#39;&#39;).replace(&#39;&lt;/style&gt;&#39;,&#39;&#39;);

    fs.writeFile(path.join(__dirname,&#39;./clock/index.css&#39;),newCss,function(err){
        if(err) return console.log(&quot;写入css样式失败&quot; + err.message)
        console.log(&#39;写入样式成功&#39;)
    }) 
}  
// 处理script的方法
function resolveScript(htmlStr){
    // 使用正则提取需要的内容
    const r1 = regScript.exec(htmlStr);
    // 将提取的内容进行replace替换操作
    const newScript = r1[0].replace(&#39;&lt;script&gt;&#39;,&#39;&#39;).replace(&#39;&lt;/script&gt;&#39;,&#39;&#39;);
    fs.writeFile(path.join(__dirname,&#39;./clock/index.js&#39;),newScript,function(err){
        if(err) return console.log(&quot;写入script样式失败&quot; + err.message)
        console.log(&#39;写入js成功&#39;)
    }) 
}  

// 处理html的方法
function resolveHtml(htmlStr){
    // 将字符串调用replace方法，把内嵌的style金额script替换link ，script
    const newHtml = htmlStr.replace(regStyle,&#39;&lt;link rel=&quot;stylesheet&quot; href=&quot;./index.css&quot;&gt;&#39;).replace(regScript,&#39;&lt;script src=&quot;./index.js&quot;&gt;&lt;/script&gt;&#39;);
    // 写入文件
    fs.writeFile(path.join(__dirname,&#39;./clock/index.html&#39;),newHtml,function(err){
        if(err) return console.log(&quot;写入html失败&quot; + err.message)
        console.log(&#39;写入html成功&#39;)
    }) 
}  
</code></pre>
<p><strong><font color='red'>1. fs.writeFile只能创建文件，不能创建目录，2. 重复使用fs.writeFile写入同一个文件的时候，后面的内容会覆盖前面的内容</font></strong></p>
<h2 id="http-">http模块</h2>
<blockquote>
<p>http 模块是 Node.is 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer0 方法，就能方便的把一台普通的电脑，变成一台Web 服务器，从而对外提供Web 资源服务。</p>
</blockquote>
<h3 id="-http-">理解http模块的作用</h3>
<blockquote>
<p>服务器和普通电脑的区别在于，服务器上安装了 web 服务器软件，例如: S、Apache 等。通过安装这些服务器软件就能把一台普通的电脑变成一台 web 服务器</p>
</blockquote>
<p>在 Nodejs 中，我们不需要使用 S、Apache 等这些第三方 web 服务器软件。因为我们可以基于 ode.js 提供的http 模块，通过几行简单的代码，就能轻松的手写一个服务器软件，从而对外提供 web 服务。</p>
<h3 id="-">服务器相关概念</h3>
<h4 id="ip-">IP地址</h4>
<blockquote>
<p>IP 地址就是互联网上每台计算机的唯一地址，因此 P 地址具有唯一性。如果把“个人电脑”比作“一台电话”，那么“IP地址”就相当于“电话号码”，只有在知道对方IP 地址的前提下，才能与对应的电脑之间进行数据通信</p>
</blockquote>
<p>IP 地址的格式:通常用“点分十进制”表示成(a.b.c.d) 的形式，其中a,b,c,d 都是 0~255 之间的十进制整数。例如:用点分十进表示的IP地址(192.168.1.1)</p>
<pre><code class="lang-shell">ping www.baidu.com
</code></pre>
<p>39.156.66.18</p>
<h4 id="-dns-">域名和域名服务器(DNS)</h4>
<blockquote>
<p>尽管IP 地址能够唯一地标记网络上的计算机，但IP地址是一长串数字，不直观，而且不便于记忆，于是人们又发明了另一套字符型的地址方案，即所谓的域名 (Domain Name) 地址</p>
</blockquote>
<p>IP地址和域名是一一对应的关系，这份对应关系存放在一种叫做域名服务器(DNS，Domain name server)的电脑中。使用者只需通过好记的域名访问对应的服务器即可，对应的转换工作由域名服务器实现。因此，域名服务器就是提供 IP 地址和域名之间的转换服务的服务器</p>
<p>DNS就是转换域名为IP地址的</p>
<p><a href="http://www.baidu.com">www.baidu.com</a></p>
<h4 id="-">端口号</h4>
<blockquote>
<p>计算机中的端口号，就好像是现实生活中的门牌号一样。通过门牌号，外卖小哥可以在整栋大楼众多的房间中，准确把外卖送到你的手命</p>
</blockquote>
<p><img src=".\pic\端口号.png" alt="端口号"></p>
<h3 id="-web-">创建基本的web服务器</h3>
<blockquote>
<p>创建 web 服务器的基本步骤</p>
</blockquote>
<ol>
<li><p>导入http 模块</p>
</li>
<li><p>创建 web 服务器实例</p>
</li>
<li><p>为服务器实例绑定 request 事件，监听客户端的请求</p>
</li>
<li><p>启动服务器</p>
</li>
</ol>
<pre><code class="lang-js">
// 1. 导入http 模块
const http = require(&#39;http&#39;);

// 2. 创建 web 服务器实例
const server = http.createServer()

// 3. 为服务器实例绑定 request 事件，监听客户端的请求

server.on(&#39;request&#39;,function(req,res){
    console.log(&quot;someone visit my web&quot;)
})
// 4. 启动服务器
server.listen(80,function(){
    console.log(&quot;server running at http://127.0.0.1&quot;)
})
</code></pre>
<pre><code class="lang-shell">node 文件名
</code></pre>
<h4 id="req-">req请求对象</h4>
<blockquote>
<p>只要服务器接收到了客户端的请求，就会调用通过server.on()为服务器绑定的request事件处理函数如果想在事件处理函数中，访问与客户端相关的数据或属性，可以使用如下的方式:</p>
</blockquote>
<pre><code class="lang-js">const http = require(&#39;http&#39;)
const server = http.createServer()

server.on(&quot;request&quot;,function(req,res){
    // req.url是客户端请求的URL地址
    const url = req.url;
    // req.method是客户端请求的method类型
    const method = req.method;
    const str = `Your request url is ${url}, and request method is ${method}`;
    console.log(str) // Your request url is /, and request method is GET
    // 在http://127.0.0.1/index.html url就是 /index.html  
})
server.listen(80,()=&gt;{
    console.log(&quot;server running at http://127.0.0.1&quot;)
})
</code></pre>
<h4 id="res-">res响应对象</h4>
<blockquote>
<p>在服务器的 request 事件处理函数中，如果想访问与服务器相关的数据或属性，可以使用如下的方式</p>
</blockquote>
<pre><code class="lang-js">const http = require(&#39;http&#39;)
const server = http.createServer()

server.on(&quot;request&quot;,(req,res)=&gt;{
    const url = req.url;
    const method = req.method;
    const str = `Your request url is ${url}, and request method is ${method}`;
    // 调用res.end()方法,向客户端响应一些内容,并结束这次请求的处理过程
    res.end(str)
})

server.listen(80,()=&gt;{
    console.log(&quot;server running at http://127.0.0.1&quot;)
})
</code></pre>
<h4 id="-">解决中文乱码问题</h4>
<blockquote>
<p>当调用 res.end0 方法，向客户端发送中文内容的时候，会出现乱码问题，此时，需要手动设置内容的编码格式</p>
</blockquote>
<pre><code class="lang-js">const http = require(&#39;http&#39;);
const server = http.createServer();

server.on(&quot;request&quot;,(req,res)=&gt;{
    // 定义的字符串
    const {url,method} = req;
    const str = `请求的url地址是${url},请求的类型是${method}`
    // res.end()将内容响应给客户端
    // res.setHeader
    //为了防止中文乱码的问题，需要设置响应头 Content-Type 的值为 text/html; charset=utf-8
    res.setHeader(&quot;Content-Type&quot;,&quot;text/html;charset=utf-8&quot;)
    res.end(str)
})

server.listen(80,()=&gt;{
    console.log(&quot;server running at http://127.0.0.1&quot;)
})
</code></pre>
<h4 id="-url-html-">根据不同的url响应不同的html内容</h4>
<ul>
<li>获取请求的 url 地址</li>
<li>设置默认的响应内容为404 Not found</li>
<li>判断用户请求的是否为/或/index.html首页</li>
<li>判断用户请求的是否为 /about.html 关于页面</li>
<li>设置 Content-Type 响应头，防止中文乱码</li>
<li>使用res.end()把内容响应给客户端</li>
</ul>
<pre><code class="lang-js">
const http = require(&#39;http&#39;);
const server = http.createServer()

server.on(&#39;request&#39;,(req,res)=&gt;{
    const {url,method} = req;
    let content = &#39;&lt;h1&gt;404 NOT found&lt;/h1&gt;&#39;;
    if(url === &quot;/&quot; || url === &quot;/index.html&quot;){
        content = &quot;&lt;h1&gt;首页&lt;/h1&gt;&quot;; 
    }else if(url === &quot;/about.html&quot;){
        content = &#39;&lt;h1&gt;关于&lt;/h1&gt;&#39;
    }
    res.setHeader(&#39;Content-Type&#39;,&#39;text/html;charset=utf-8&#39;);
    res.end(content);
})

server.listen(80,()=&gt;{
    console.log(&quot;http://127.0.0.1&quot;)
})
</code></pre>
<h3 id="-clock-web-">案例:实现clock时钟的web服务器</h3>
<blockquote>
<p>把文件的实际保存路径,作为每个资源的请求的url地址</p>
</blockquote>
<p><img src=".\pic\时钟http.png" alt="http时钟案例"></p>
<blockquote>
<p>实现步骤</p>
<ul>
<li>导入需要的模块</li>
<li>创建基本的web服务器</li>
<li>将资源的请求url地址映射为文件的存放路径</li>
<li>读取文件内容并响应给客户端</li>
<li>优化资源的请求路径</li>
</ul>
</blockquote>
<pre><code class="lang-js">const http = require(&#39;http&#39;);
const fs = require(&#39;fs&#39;)
const path = require(&#39;path&#39;)
const server = http.createServer()

server.on(&#39;request&#39;,(req,res)=&gt;{
    const url = req.url;
    // 获取url地址
    // /clock/index.html  /clock/index.css  /clock/index.js
    // 把请求的url地址映射为具体文件的存放路径
    const fpath = path.join(__dirname,url);
    // const htmlStr = path.join(__dirname,&#39;../../clock/index.html&#39;)
    // const cssStr = path.join(__dirname,&#39;../../clock/index.css&#39;)
    // const jsStr = path.join(__dirname,&#39;../../clock/index.js&#39;)
    // if(url === &quot;/index.html&quot; || url === &quot;/&quot;){
    //     res.setHeader(&#39;ContentType&#39;,&quot;text/html;charset=utf-8&quot;);
    //     res.end(htmlStr,cssStr,jsStr)
    // }else{
    //     res.end(&quot;&lt;h1&gt;404&lt;/h1&gt;&quot;)
    // }
    // 读取文件的内容
    fs.readFile(fpath,&#39;utf-8&#39;,(err,dataStr)=&gt;{
        // 读取失败
        if(err) return res.end(&#39;404 not found&#39;) 
        res.end(dataStr)
    })
})

server.listen(80,()=&gt;{
    console.log(&quot;server running at http://127.0.0.1&quot;)
})
</code></pre>
<p>优化</p>
<pre><code class="lang-js">const http = require(&#39;http&#39;);
const fs = require(&#39;fs&#39;)
const path = require(&#39;path&#39;)
const server = http.createServer()

server.on(&#39;request&#39;,(req,res)=&gt;{
    const url = req.url;
    let fpath =&#39;&#39;;
    if(url === &#39;/&#39;){
        fpath = path.join(__dirname,&quot;/clock/index.html&quot;)
    }else{
        fpath = path.join(__dirname,&#39;/clock&#39;,url)
    }
    // 读取文件的内容
    fs.readFile(fpath,&#39;utf-8&#39;,(err,dataStr)=&gt;{
        // 读取失败
        if(err) return res.end(&#39;404 not found&#39;) 
        res.end(dataStr)
    })
})

server.listen(80,()=&gt;{
    console.log(&quot;server running at http://127.0.0.1&quot;)
})
</code></pre>
<h2 id="-">模块化</h2>
<blockquote>
<p>模块化是指解决一个复杂问题时，自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说，模块是可组合、分解和更换的单元。</p>
</blockquote>
<p>编程中的模块化</p>
<blockquote>
<p>编程领域中的模块化，就是遵守固定的规则，把一个大文件拆成独立并互相依赖的多个小模块.</p>
</blockquote>
<p>把代码进行模块化拆分的好处:</p>
<ul>
<li>提高了代码的复用性</li>
<li>提高了代码的可维护性</li>
<li>可以实现按需加载</li>
</ul>
<h3 id="-">模块化规范</h3>
<p>模块化规范就是对代码进行模块化的拆分与组合时，需要遵守的那些规则。
例如:</p>
<ol>
<li>使用什么样的语法格式来引用模块</li>
<li>在模块中使用什么样的语法格式向外暴露成员</li>
</ol>
<h3 id="nodejs-">nodeJs分类</h3>
<p>根据模块的来源，可以分为3大类：</p>
<ul>
<li>内置模块(内置模块是由 Node.js 官方提供的，例如 fs，path，http 等)</li>
<li>自定义模块(用户创建的每个 .js 文件，都是自定义模块)</li>
<li>第三方模块(由第三方开发出来的模块，并非官方提供的内置模块，也不是用户创建的自定义模块，使用前需要先下载</li>
</ul>
<h3 id="-">加载模块</h3>
<blockquote>
<p>使用强大的 require0 方法，可以加载需要的内置模块、用户自定义模块、第三方模块进行使用。例如:</p>
</blockquote>
<pre><code class="lang-js">// 1.加载内置的 fs 模块
const fs = require( &#39;fs &#39; )
// 2.加载用户的自定义模块
 const custom = require( &#39; ./custom.js&#39; )
 // 3，加载第三方模块(关于第三方模块的下载和使用，会在后面的课程中进行专门的讲解)
 const moment = require( &#39;moment &#39;)
</code></pre>
<p><strong>注意：</strong><font color="red">使用require()方法加载其他模块的时候，会执行加载模块中的代码</font></p>
<blockquote>
<p>in.js</p>
<pre><code class="lang-js">console.log(&quot;加载了模块&quot;)
</code></pre>
</blockquote>
<blockquote>
<p>模块化.js</p>
</blockquote>
<pre><code class="lang-js">// 注意: 在使用 require 加载用户自定义模块期间
// 可以省略 .js 的后缀名
const m1 = require(&quot;./in.js&quot;)
console.log(m1)
</code></pre>
<h3 id="nodejs-">nodeJs模块作用域</h3>
<blockquote>
<p>和函数作用域类似，在自定义模块中定义的变量、方法等成员，只能在当前模块内被访问，这种模块级别的访问限制，叫做模块作用域。</p>
</blockquote>
<p><em>模块作用域好处：</em></p>
<ul>
<li>防止全局污染，无法被外界访问</li>
</ul>
<h3 id="module-">module对象</h3>
<blockquote>
<p>在每个js自定义模块中都有一个module 对象,它里面存储了和当前模块有关的信息
<code>`</code>js
console.log(module)
/<em>
Module {
  id: &#39;.&#39;,
  path: &#39;C:\Users\Administrator\Desktop\python全
栈\BaiduSyncdisk\node\code\feil\模块化&#39;,
  exports: {},
  filename: &#39;C:\Users\Administrator\Desktop\python全栈\BaiduSyncdisk\node\code\feil\模块化\02module.js&#39;,
  loaded: false,
  children: [],
  paths: [
    &#39;C:\Users\Administrator\Desktop\python全栈\BaiduSyncdisk\node\code\feil\模块化\node_modules&#39;,
    &#39;C:\Users\Administrator\Desktop\python全栈\BaiduSyncdisk\node\code\feil\node_modules&#39;,<br>    &#39;C:\Users\Administrator\Desktop\python全栈\BaiduSyncdisk\node\code\node_modules&#39;,
    &#39;C:\Users\Administrator\Desktop\python全栈\BaiduSyncdisk\node\node_modules&#39;,
    &#39;C:\Users\Administrator\Desktop\python全栈\BaiduSyncdisk\node_modules&#39;,
    &#39;C:\Users\Administrator\Desktop\python全栈\node_modules&#39;,
    &#39;C:\Users\Administrator\Desktop\node_modules&#39;,
    &#39;C:\Users\Administrator\node_modules&#39;,<br>    &#39;C:\Users\node_modules&#39;,
    &#39;C:\node_modules&#39;
  ]
}
</em>/</p>
</blockquote>
<pre><code>
#### module.exports对象

&gt; 在自定义模块中，可以使用 module.exports 对象，将模块内的成员共享出去，供外界使用

```js
var userName = &quot;颤三&quot;;
var user = &quot;管理员&quot;;
// 向module.exports对象上挂在了一个username属性
module.exports.userName = &quot;张三&quot;;
// 向module.exports对象上挂载了 salHello方法
module.exports.sayHello = function(){
    console.log(userName)
}

module.exports.user = user;
</code></pre><p><em>使用 require0 方法导入模块时，导入的结果，永远以 module.exports 指向的对象为准</em></p>
<pre><code class="lang-js">//1. 向module.exports 属性上挂载了.username1
module.exports.username = &quot;张三&quot;;

// 2.module.exports 对象上挂载方法 
module.exports.sayHellomodule.exports.sayHello = function(){
    console.log(&quot;Hello!&quot;)
}
// 3.让 module.exports 指向一个全新的对象
module.exports = {
    nickname:&quot;小黑&quot;,
    sayhi () {
        console.log(&#39;Hi! &#39;)
    }
}
</code></pre>
<h3 id="exports-">exports对象</h3>
<blockquote>
<p>由于 module.exports 单词写起来比较复杂，为了简化向外共享成员的代码，Node 提供了exports 对象。默认情况exports 和 module.exports 指向同一个对象。最终共享的结果，还是以 module.exports 指向的对象为准</p>
</blockquote>
<pre><code class="lang-js">console.log(exports === module.exports) // true
</code></pre>
<font color="green">require()模块，得到的永远是module.exports指向的对象;建议不要在同一个模块中同时使用exports和module.exports</font>

<h3 id="nodejs-">nodeJs中的模块规范</h3>
<blockquote>
<p>Node.is 遵循了 CommonJS 模块化规范，CommonJS 规定了模块的特性和各模块之间如何相互依赖</p>
</blockquote>
<ol>
<li>每个模块内部，module变量代表当前模块。</li>
<li>module 变量是一个对象，它的 exports 属性(即 module.exports) 是对外的接口。</li>
<li>加载某个模块，其实是加载该模块的 module.exports 属性。require() 方法用于加载模块.</li>
</ol>
<h2 id="-">包</h2>
<blockquote>
<p>nodeJs中的第三方模块又叫做包，不同于 Node.js 中的内置模块与自定义模块，包是由第三方个人或团队开发出来的，免费供所有人使用</p>
</blockquote>
<h3 id="-">为什么需要包</h3>
<blockquote>
<p>由于 Node.js 的内置模块仅提供了一些底层的 API，导致在基于内置模块进行项目开发的时，效率很低包是基于内置模块封装出来的，提供了更高级、更方便的 API，极大的提高了开发效率。包和内置模块之间的关系，类似于Jquery和浏览器内置API之间的关系</p>
</blockquote>
<h3 id="-">下载包</h3>
<p><a href="https://www.npmjs.com/">https://www.npmjs.com/</a>
<a href="https://registry.npmjs.org/">https://registry.npmjs.org/</a></p>
<pre><code class="lang-shell">node -v
</code></pre>
<p>下载包</p>
<pre><code class="lang-shell">npm install 包完整的名字
</code></pre>
<pre><code class="lang-shell">npm i 包完整的名字
</code></pre>
<p>简单的使用包</p>
<pre><code class="lang-js">// 导入包
const moment = require(&#39;moment&#39;);
const dt = moment().format(&quot;YYYY-MM-DD HH:mm:ss&quot;)

console.log(dt)
</code></pre>
<h3 id="-">安装了包之后多的文件作用</h3>
<p>初次装包完成后，在项目文件夹下多一个叫做 node_modules 的文件夹和 package-lock.json 的配置文件
其中:
node_modules 文件夹用来存放所有已安装到项目中的包。require()导入第三方包时，就是从这个目录中香找并加载包，package-lock.json 配置文件用来记录 node_modules 目录下的每一个包的下载信息，例包的名字、版本号、下载地址等</p>
<blockquote>
<p>默认情况下，使用npm install 命令安装包的时候会自动安装最新版本的包。如果需要安装指定版本的包，可以在包名之后，通过 @ 符号指定具体的版本，例如:</p>
<pre><code class="lang-shell">npm i moment@2.22.2
</code></pre>
</blockquote>
<h4 id="-">包的语义化版本规范</h4>
<p>包的版本号是以“点分十进制”形式进行定义的，总共有三位数字，例如 2.24.0其中每一位数字所代表的的含义如下:</p>
<ol>
<li>第1位数字:大版本</li>
<li>第2位数字:功能版本</li>
<li>第3位数字:Bug修复版本</li>
</ol>
<p>版本号提升的规则:<font color="yellow">只要前面的版本号增长了，则后面的版本号归零</font></p>
<h3 id="-">包管理配置文件</h3>
<blockquote>
<p>npm 规定，在项目根目录中，必须提供一个叫做 package.json 的包管理配置文件。用来记录与项目有关的一些配置信息。例如:</p>
<ul>
<li>项目的名称版本号、描述等</li>
<li>项目中都用到了哪些包</li>
<li>哪些包只在开发期间会用到</li>
<li>那些包在开发和部署时都需要用到</li>
</ul>
</blockquote>
<p><img src=".\pic\包管理.png" alt="包管理"></p>
<p><img src=".\pic\创建packjson.png" alt="创建packjson"></p>
<p><img src=".\pic\dependencies节点.png" alt="dependencies节点"></p>
<pre><code class="lang-shell">npm i
</code></pre>
<font color="red">可以一次性下载所有包</font>

<pre><code class="lang-shell">npm uninstall 包名称
</code></pre>
<font color="red">卸载包</font>

<p><img src=".\pic\dev节点.png" alt="dev节点"></p>
<p><em>解决npm下载慢的问题</em></p>
<p>使用淘宝镜像</p>
<pre><code class="lang-shell"># 查看当前下包镜像地址
npm config get registry
# 将下包的地址换为淘宝地址
npm config set registry=https://registry.npm.taobao.org/
</code></pre>
<p><img src=".\pic\nrm.png" alt="nrm"></p>
<h3 id="-">包的分类</h3>
<ol>
<li>项目包<blockquote>
<p>那些被安装到项目的 node modules 目录中的包，都是项目包</p>
</blockquote>
</li>
</ol>
<p>项目包又分为两类，分别是:</p>
<ul>
<li>开发赖包(被记录到devDependencies 节点中的包，只在开发期间会用到)</li>
<li>核心依赖包(被记录到 dependencies 节点中的包，在开发期间和项目上线之后都会用到)</li>
</ul>
<pre><code class="lang-shell"># 开发依赖包（会被记录到被记录到devDependencies）
npm i 包名 -D 
# 核心依赖包（会被记录到被记录到dependencies）
npm i
</code></pre>
<ol start="2">
<li>全局包</li>
</ol>
<blockquote>
<p>在执行 npm install 命令时，如果提供了 -g 参数，则会把包安装为全局包全局包会被安装到 C:\Users\用户目录\AppDataRoaming\npm\node modules 目录下</p>
</blockquote>
<pre><code class="lang-shell"># 全局安装指定的包
npm i 包名 -g 
# 卸载全局包
npm uninstall 包名 -g

</code></pre>
<ul>
<li><p>只有工具性质的包，才有全局安装的必要性。因为它们提供了好用的终端命令判断</p>
</li>
<li><p>某个包是否需要全局安装后才能使用，可以参考官方提供的使用说明即可</p>
</li>
</ul>
<h4 id="i5ting_toc">i5ting_toc</h4>
<p>可以将md文档转为html的工具</p>
<pre><code class="lang-shell">
# 将 i5ting_toc 安装为全局包
npm install -g i5ting_toc
# 用 i5ting_toc，轻松实现 md 转 html 的功能
i5ting_toc -f 要转换的md文件路径 -o
</code></pre>

          	</article>
        </div>
		</div>
  </body>
</html>
<script type="text/javascript" src="toc/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="toc/js/jquery.ztree.all-3.5.min.js"></script>
<script type="text/javascript" src="toc/js/ztree_toc.js"></script>
<script type="text/javascript" src="toc_conf.js"></script>

<SCRIPT type="text/javascript" >
<!--
$(document).ready(function(){
    var css_conf = eval(markdown_panel_style);
    $('#readme').css(css_conf)
    
    var conf = eval(jquery_ztree_toc_opts);
		$('#tree').ztree_toc(conf);
});
//-->
</SCRIPT>